package fr.univnantes.lina.ftbcleaner;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import fr.univnantes.lina.ftbcleaner.DesambiguateUtil;
import fr.univnantes.lina.ftbcleaner.FTBPropertiesMultiWordCollector;
import fr.univnantes.lina.ftbcleaner.MultiWordDesambiguationCase;
import fr.univnantes.lina.ftbcleaner.WordLemma;
import fr.univnantes.lina.ftbcleaner.WordLemmas;
import fr.univnantes.lina.javautil.CollectionUtilities;


public class FTBPropertiesMultiWordCompiler extends
		FTBPropertiesMultiWordCollector {

	public FTBPropertiesMultiWordCompiler() {
		super();
	}

	/**
	 * After having collected information coming from distinct occurrences of MW, generalize the information
	 */
	public void compilePropertiesFromMultiWords(WordLemmas multiWordLemmas) {
	
		Map<String,WordLemma> multiWordsExpressionHashMap = multiWordLemmas.getMultiWordLemmaMap(); 
		Map<String,Set<WordLemma>> multiWordsExpressionFirstWordMap  = multiWordLemmas.getMultiWordFirstWordMap();
	
		int mwWiAtLeastOneOccWiOneWordWoCatintsValue = 0;
		int mwLemmaWiNoCatintsPb = 0;
		int mwOccWiNoCatintsPb = 0;
	
		int mwWoCatints = 0;
		int mwWiOnlyOneCatints = 0;
		int mwWiOnlyOneCatintsButNotCoveringTheWholeMW = 0;
		int mwWiMultipleCatintsButIdentical = 0;
	
		int mwWiMultipleCatintsButIdenticalButNotCoveringTheWholeMW = 0;
		int mwWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalient = 0;// heuristic FB
		int mwWiMultipleCatintsNotIdenticalWoOneSufficientlyMoreSalientButWiOneCoveringtheWhole = 0;
		int mwWiMultipleCatintsNotIdenticalWoOneSufficientlyMoreSalientAndWoOneCoveringtheWhole = 0;
		int mwWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalientNotCoveringTheWholeMWButWiOneCoveringtheWhole = 0;
		int mwWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalientNotCoveringTheWholeMWButWoOneCoveringtheWhole = 0;
	
		int numberOfMWOccurrenceWiACatintIssue = 0;
	
		// TODO
		//String mostProbableCatintSequence = "";
	
		Iterator<String> multiWordsExpressionHashMapKeyIterator = 	multiWordsExpressionHashMap.keySet().iterator();
	
		// For each lemma
		while (multiWordsExpressionHashMapKeyIterator.hasNext()) {
			WordLemma aMultiWordLemma = multiWordsExpressionHashMap.get(multiWordsExpressionHashMapKeyIterator.next());
	
			//			Boolean canBeDesambiguated = false;
	
			// If the current MW has empty catints
			if (aMultiWordLemma.getNumberOfNullCatintValue() >0) {
				mwWiAtLeastOneOccWiOneWordWoCatintsValue++;
				numberOfMWOccurrenceWiACatintIssue += aMultiWordLemma.getOccurrence();
	
				List<String> aMultiWordLemmaCatintsList = aMultiWordLemma.getCatintsArrayList();
				// if no interpretation is available among the other mw occurrences
				if (aMultiWordLemmaCatintsList.size() == 0) {
					mwWoCatints++;
					aMultiWordLemma.setDesambiguisationCase(MultiWordDesambiguationCase.MWWoCatints);
				}
				// if only one interpretation is available among the other mw occurrences
				// i.e. aMWECatintsList.size() == 1
				// and numberOfPartOfWordsNotPartOfAmalgame
				else if (aMultiWordLemmaCatintsList.size() == 1) {
					// searching the first longest catints sequence
					String currentCatints = aMultiWordLemmaCatintsList.get(0); //catintsArrayListIterator.next();
					String[] currentCatintsArray =currentCatints.split(" ");
					if (currentCatintsArray.length == aMultiWordLemma.getSize()) {
	
						mwWiOnlyOneCatints++;
						aMultiWordLemma.setDesambiguisationCase(MultiWordDesambiguationCase.MWWiOnlyOneCatintsWhichCoversTheWholeMW);
						//						canBeDesambiguated = true;
						//				mostProbableCatintSequence = currentCatints;
						aMultiWordLemma.setUniqCommonCatintsSequence(currentCatints);
					}
					else {
						mwWiOnlyOneCatintsButNotCoveringTheWholeMW++;
						aMultiWordLemma.setDesambiguisationCase(MultiWordDesambiguationCase.MWWiOnlyOneCatintsButNotCoveringTheWholeMW);
						//						aMWE.display();
					}
				}
				// if multiple interpretation available among the other mw occurrences
				else if (aMultiWordLemmaCatintsList.size() > 1) {
					String[] aMWECatintsArray = aMultiWordLemmaCatintsList.toArray(new String[0]);
					Boolean areAllInterpretationIdentical = true;
	
					Map<String,Integer> aMWECatintsMap = new HashMap<String,Integer>();
	
					String firstLongestCatintsSequence = "";
					int firstLongestCatintsSequenceSize = 0;
	
					// compute if All the catints are Identical 
					// the number of each catints forms
					// the first longest catints sequence
					for (int i = 0 ; i < aMWECatintsArray.length ; i++) {
						if ((i>0) && (!aMWECatintsArray[i-1].equalsIgnoreCase(aMWECatintsArray[i])))  
							areAllInterpretationIdentical = false;
						if (!aMWECatintsMap.containsKey(aMWECatintsArray[i])) 
							aMWECatintsMap.put(aMWECatintsArray[i], new Integer(1));
						else 
							aMWECatintsMap.put(aMWECatintsArray[i], aMWECatintsMap.get(aMWECatintsArray[i])+1);
						String currentCatints = aMWECatintsArray[i];
						String[] currentCatintsArray =currentCatints.split(" ");
						if (currentCatintsArray.length > firstLongestCatintsSequenceSize) {
							firstLongestCatintsSequence = currentCatints;
							firstLongestCatintsSequenceSize = currentCatintsArray.length ;
						}
					}
	
					// the multiple catints sequence are all identical
					// concequently the firstLongestCatintsSequence and firstLongestCatintsSequenceSize are the same for all
					if (areAllInterpretationIdentical) { 
						// mwWiOnlyOneCatints++; 
						// and cover the whole mw
						if (firstLongestCatintsSequenceSize == aMultiWordLemma.getSize()) {
							mwWiMultipleCatintsButIdentical++;
							aMultiWordLemma.setDesambiguisationCase(MultiWordDesambiguationCase.MWWiMultipleCatintsButIdenticalWhichCoversTheWholeMW);
	
							//							canBeDesambiguated = true;
							//				mostProbableCatintSequence = aMWECatintsArray[0];
							aMultiWordLemma.setUniqCommonCatintsSequence(aMWECatintsArray[0]);
						}
						// and do not cover the whole mw
						else {
							mwWiMultipleCatintsButIdenticalButNotCoveringTheWholeMW++;
							aMultiWordLemma.setDesambiguisationCase(MultiWordDesambiguationCase.MWWiMultipleCatintsButIdenticalButNotCoveringTheWholeMW);
						}
					}
	
					else {
						// among the forms which are not identical, compute the number of sufficiently more salient
						// we evaluate if one catints is more salient than others (based on FB heuristic)
	
						TreeMap<String,Integer> aSortedMWECatintsMap = CollectionUtilities.sortStringIntegerHashMapByValue (aMWECatintsMap);
	
	
						// if the FB heuristic fires
						if (DesambiguateUtil.isTheFirstFormMoreSalientThanOthersBasedOnFBHeuristic(aSortedMWECatintsMap)) {
	
							String[] aSortedMWECatintsMapArray = aSortedMWECatintsMap.firstKey().split(" ");
	
							// is the most FB salient catints sequence covering the whole mw
							// if yes, it is also the longest (firstLongestCatintsSequenceSize)
							if (aSortedMWECatintsMapArray.length == aMultiWordLemma.getSize()) {
								mwWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalient++;
								aMultiWordLemma.setDesambiguisationCase(MultiWordDesambiguationCase.MWWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalientWhichCoversTheWholeMW);
								//								canBeDesambiguated = true;
								//	mostProbableCatintSequence = aSortedMWECatintsMap.firstKey();
								aMultiWordLemma.setMostFBSalientCatintsSequence(aSortedMWECatintsMap.firstKey());
	
							}
							else { 
								// does it exist a catints sequence covering the whole mw
								if (firstLongestCatintsSequenceSize == aMultiWordLemma.getSize()) {
									mwWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalientNotCoveringTheWholeMWButWiOneCoveringtheWhole++;
									aMultiWordLemma.setDesambiguisationCase(MultiWordDesambiguationCase.MWWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalientNotCoveringTheWholeMWButWiOneCoveringtheWhole);
	
									//									canBeDesambiguated = true;
									// TODO could be by size of importance
									//		mostProbableCatintSequence = firstLongestCatintsSequence;
									aMultiWordLemma.setMostFrequentCoveringCatintsSequence(firstLongestCatintsSequence);
	
								}
								// and do not cover the whole mw
								else {
									mwWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalientNotCoveringTheWholeMWButWoOneCoveringtheWhole++;
									aMultiWordLemma.setDesambiguisationCase(MultiWordDesambiguationCase.MWWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalientNotCoveringTheWholeMWButWoOneCoveringtheWhole);
	
								}
							}
						}
						// Wi No sufficiently 
						else {
							// but with one longest covering the whole
							if (firstLongestCatintsSequenceSize == aMultiWordLemma.getSize()) {
								mwWiMultipleCatintsNotIdenticalWoOneSufficientlyMoreSalientButWiOneCoveringtheWhole++;
								aMultiWordLemma.setDesambiguisationCase(MultiWordDesambiguationCase.MWWiMultipleCatintsNotIdenticalWoOneSufficientlyMoreSalientButWiOneCoveringtheWhole);
	
								//								canBeDesambiguated = true;
								//		mostProbableCatintSequence = firstLongestCatintsSequence;
								aMultiWordLemma.setMostFrequentCoveringCatintsSequence(firstLongestCatintsSequence);
	
							}
							// and do not cover the whole mw
							else {
								mwWiMultipleCatintsNotIdenticalWoOneSufficientlyMoreSalientAndWoOneCoveringtheWhole++;
								aMultiWordLemma.setDesambiguisationCase(MultiWordDesambiguationCase.MWWiMultipleCatintsNotIdenticalWoOneSufficientlyMoreSalientAndWoOneCoveringtheWhole);
	
							}
						}
					}
				}
	
				// TODO in compilePropertiesFromMultiWords 
				// remove addMostProbableCatintSequence and instead of, 
				// add aWordOccurrences here ? 
				// No. 
				// Add three string variables in MWLemma and define them in the previous code lines
				// Modify desambiguate where getMostProbableCatintSequence is called
				// In addition, in search where addMostProbableCatintSequence is called
				// change it for a add aWordOccurrences CollectionUtilities.incrementKeyValueCounter(word2CatMap, currentWordFormOcc, catSW);
	
				// Add the most probable assumed catint sequence
				/*if (!mostProbableCatintSequence.equalsIgnoreCase("")) {
					// For each lemma word forms 
					// assign the whatever most probable catint sequence identified to it
					Iterator <String >wordsIter = aMultiWordLemma.getWordForms().iterator();
					while (wordsIter.hasNext()) {
						String wordsString = wordsIter.next();
						aMultiWordLemma.addMostProbableCatintSequence(wordsString, mostProbableCatintSequence);
					}
				}*/
	
				// build a map of multiwords expression first words and multiwords expression
				// for each first word of all the word forms of the current MW
				Iterator<String> wordsIterator = aMultiWordLemma.getWordForms().iterator();
				while (wordsIterator.hasNext()) {
					String wordsString = wordsIterator.next();
					String wordString[] = wordsString.split(" ");
	
					// add the current MW to the set of MW mapped by the first word form
					if (multiWordsExpressionFirstWordMap.containsKey(wordString[0])) {
						Set<WordLemma> mWSet = multiWordsExpressionFirstWordMap.get(wordString[0]);
						mWSet.add(aMultiWordLemma);
					}
					else {
						Set<WordLemma> mWSet = new HashSet<WordLemma>();
						mWSet.add(aMultiWordLemma);
						multiWordsExpressionFirstWordMap.put(wordString[0], mWSet);
					}
	
				}
			}
			else {
				mwLemmaWiNoCatintsPb++;
				mwOccWiNoCatintsPb+= aMultiWordLemma.getOccurrence();
			}
	
		}
	
		//System.err.println("Info: total # of multi-words lemma = "+ (mwWiAtLeastOneOccWiOneWordWoCatintsValue + mwLemmaWiNoCatintsPb)
		//		+ " (with some catint issue "+ mwWiAtLeastOneOccWiOneWordWoCatintsValue
		//		+", without "+ mwLemmaWiNoCatintsPb+")");
		//System.err.println("Info: total # of multi-words occurrences  = "+ (numberOfMWOccurrenceWiACatintIssue + mwOccWiNoCatintsPb)
		//		+ " (with a catint issue "+ numberOfMWOccurrenceWiACatintIssue
		//		+", without "+ mwOccWiNoCatintsPb+")");
	
		System.err.println("Info: # of multi-words without catint issue lemma = "+ (mwLemmaWiNoCatintsPb)
				+ ", occurrences = "+ mwOccWiNoCatintsPb);
		System.err.println("Info: # of multi-words with catint issue lemma = "+ (mwWiAtLeastOneOccWiOneWordWoCatintsValue)
				+ ", occurences = "+ numberOfMWOccurrenceWiACatintIssue);
	
		//System.err.println("Info: # of multi-words lemma without catint issue  = "+mwLemmaWiNoCatintsPb);
		//System.err.println("Info: # of multi-words occurrences without catint issue  = "+mwOccWiNoCatintsPb);
	
		//System.err.println("Info: # of multi-words lemma with a catint issue (at least one word partOf wi no catint value) = "+mwWiAtLeastOneOccWiOneWordWoCatintsValue);
		//System.err.println("Info: # of multi-words occurrences with a catint issue (at least one word partOf wi no catint value) = "+numberOfMWOccurrenceWiACatintIssue);
	
	
		System.err.println("Info: # of multi-words lemma with no catints values = "+mwWoCatints);
		// base de calcul N, patron des patrons NC,  Trade Union Congress NP, remettre en question V, donner l'impressionV, 1 287 D/PRO, sur commande P,   à la mémoire de P
	
		System.err.println("Info: # of multi-words lemma with only one catints sequence which covers the whole mw = "+mwWiOnlyOneCatints);
	
		System.err.println("Info: # of multi-words lemma with only one catints sequence which do not covers the whole mw = "
				+mwWiOnlyOneCatintsButNotCoveringTheWholeMW);
	
		System.err.println("Info: # of multi-words lemma with multiple identical catints sequences which cover the whole mw  = "
				+mwWiMultipleCatintsButIdentical);
		// produit laitier  , mettre à la disposition, le Pas-de-Calais
	
		System.err.println("Info: # of multi-words lemma with multiple identical catints sequences and none of them covers the whole mw  = "
				+mwWiMultipleCatintsButIdenticalButNotCoveringTheWholeMW);
	
		System.err.println("Info: # of multi-words lemma with multiple distinct catints sequences and one sufficiently salient covering the whole mw = "+
				mwWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalient);
	
		System.err.println("Info: # of multi-words lemma with multiple distinct catints sequences and no sufficiently salient but one catints covering the whole mw = "+
				mwWiMultipleCatintsNotIdenticalWoOneSufficientlyMoreSalientButWiOneCoveringtheWhole);
	
		System.err.println("Info: # of multi-words lemma with multiple distinct catints sequences and no sufficiently salient and no catints covering the whole mw = "+
				mwWiMultipleCatintsNotIdenticalWoOneSufficientlyMoreSalientAndWoOneCoveringtheWhole);
	
		System.err.println("Info: # of multi-words lemma with multiple distinct catints sequences and one sufficiently salient not covering the whole mw but wi one catint covering the whole = "+
				mwWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalientNotCoveringTheWholeMWButWiOneCoveringtheWhole);
	
		System.err.println("Info: # of multi-words lemma with multiple distinct catints sequences and one sufficiently salient not covering the whole mw and wi none catint covering the whole = "+
				mwWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalientNotCoveringTheWholeMWButWoOneCoveringtheWhole);
	
	}

}